home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / dsksl091.zip / dsl.c < prev    next >
C/C++ Source or Header  |  1997-06-03  |  15KB  |  670 lines

  1. /*
  2.  * $Source: e:/source/driver/sleep/RCS/dsl.c,v $
  3.  * $Revision: 1.6 $
  4.  * $Date: 1997/06/03 23:28:24 $
  5.  * $Author: vitus $
  6.  *
  7.  * Displays and/or modifies device sleeping timers.  Sample
  8.  * application.
  9.  * Compile with...
  10.  * IBM CSet++ 2.1    - icc -Q -W2all -O [-Gd] dsl.c
  11.  * GNU C 2.7.0        - gcc -Wall -O3 [-Zcrtdll] dsl.c
  12.  * WatCom C/C++ 10.5    - wcl386 -zq -bt=os2v2 -3s -wx -oax dsl.c
  13.  *
  14.  * $Log: dsl.c,v $
  15.  * Revision 1.6  1997/06/03 23:28:24  vitus
  16.  * - expanded '-?' output
  17.  *
  18.  * Revision 1.5  1997/05/07 23:53:27  vitus
  19.  * - tests both forms of version query
  20.  * - calls READ_MSGS to get size of required buffer
  21.  *
  22.  * Revision 1.4  1997/04/07 03:35:03  vitus
  23.  * Changed program options
  24.  * Added possibility to change/display timeout counter
  25.  *
  26.  * Revision 1.3  1997/04/05 01:50:24  vitus
  27.  * DisplayVersion shows registered-flag
  28.  * Test: display datasize before/after call
  29.  *
  30.  * Revision 1.2  1997/03/05 21:58:26  vitus
  31.  * Changed for new timeout in seconds
  32.  * Added mode to display saved messages
  33.  *
  34.  * Revision 1.1  1997/02/06 01:25:42  vitus
  35.  * Initial revision
  36.  *
  37.  */
  38. static char const id[]="$Id: dsl.c,v 1.6 1997/06/03 23:28:24 vitus Exp $";
  39.  
  40. #include <stdio.h>
  41. #include <string.h>
  42. #include <stdlib.h>
  43.  
  44. #define INCL_DOS
  45. #include <os2.h>
  46.  
  47. #include "dskslpub.h"
  48.  
  49.  
  50.  
  51.  
  52. #define DEVICENAME    "dsleeps$"        /* DSKSLEEP.FLT is actual... */
  53.  
  54. #define MODE_DISPLAY    0
  55. #define MODE_CHANGE    1
  56. #define MODE_MESSAGE    2
  57. #define MODE_QUERY    3
  58. #define MODE_IMMEDIATE    4
  59.  
  60.  
  61. /*
  62.  * Global variables
  63.  */
  64. char    szPrgName[_MAX_PATH];
  65. char    fVerbose = 0;
  66. char    fMode = MODE_DISPLAY;
  67.  
  68.  
  69. void
  70. usage(void)
  71. {
  72.     printf("usage: %s [-?] [-m | -q | {-c|-i} a1,d1,t1 [a2,d2,t2 ...]]\n", szPrgName);
  73. }
  74. void
  75. help(void)
  76. {
  77.     usage();
  78.     printf("\nDisplays and/or changes sleeping times/timers\n"
  79.        " -m\tdisplay saved messages\n"
  80.        " -c\tpermanent change of disk timeout (minutes)\n"
  81.        " -q\tdisplay *seconds* left until disk stops\n"
  82.        " -i\tchange *seconds* left until disk stops\n"
  83.        " -?\tthis text\n\n"
  84.        " a,d,t\ta value ('t' minutes or seconds) for disk 'd' on adapter 'a'\n"
  85.        "Examples:\n"
  86.        " 'dsl'\t\t\tdisplay current timeout values\n"
  87.        " 'dsl -c 1,0,10'\tchange timeout for first disk on second adapter\n\t\t\tto 10 minutes\n"
  88.        " 'dsl -c 0,0,0'\t\tchange timeout for first disk on first adapter\n\t\t\tto 0 minutes (never stop that disk)\n"
  89.        " 'dsl -i 1,1,0'\t\tset timer for second disk on second adapter\n\t\t\tto 0 seconds (immediately stop that disk)\n"
  90.        "\nRemember that any access to a disk will reset it's timer value.  So '-i'\nmight not work for you.\n");
  91. }
  92.  
  93.  
  94.  
  95.  
  96. /*#
  97.  * NAME
  98.  *    DisplayVersion
  99.  * CALL
  100.  *    DisplayVersion(hd)
  101.  * PARAMETER
  102.  *    hd        handle to open device
  103.  * RETURNS
  104.  *    OS error code
  105.  * GLOBAL
  106.  *    none
  107.  * DESPRIPTION
  108.  *    Displays driver version.
  109.  * REMARKS
  110.  */
  111. int
  112. DisplayVersion(HFILE hd)
  113. {
  114.     APIRET        rc;
  115.     DSKSL_VER_DATA    data;
  116.     ULONG        datasize;
  117.  
  118.  
  119.     /* Issue IOCtl in two fashions
  120.      * - 16bit data: only version
  121.      * - DSKSL_VER_DATA: registered info, too */
  122.  
  123.     do
  124.     {
  125.     datasize = sizeof(data.version);
  126.     rc = DosDevIOCtl(hd, IOCTL_DSKSLEEP_CATEGORY, DSKSL_QUERY_VERSION,
  127.              NULL, 0, NULL, &data.version, datasize, &datasize);
  128.     if( rc )
  129.     {
  130.         fprintf(stderr, "DSKSL_QUERY_VERSION - error %lu\n", rc);
  131.         break;
  132.     }
  133.     printf("Installed: DSKSLEEP.FLT %u.%02u\n",
  134.            HIBYTE(data.version), LOBYTE(data.version));
  135.  
  136.     datasize = sizeof(data);
  137.     rc = DosDevIOCtl(hd, IOCTL_DSKSLEEP_CATEGORY, DSKSL_QUERY_VERSION,
  138.              NULL, 0, NULL, &data, datasize, &datasize);
  139.     if( rc )
  140.     {
  141.         fprintf(stderr, "DSKSL_QUERY_VERSION - error %lu\n", rc);
  142.         break;
  143.     }
  144.  
  145.     printf("Installed: DSKSLEEP.FLT %u.%02u (%s)\n",
  146.            HIBYTE(data.version), LOBYTE(data.version),
  147.            (data.flags&0x01 ? "registered" : "unregistered"));
  148.     }
  149.     while( 0 );
  150.  
  151.     return (int)rc;
  152. }
  153.  
  154.  
  155.  
  156.  
  157. /*#
  158.  * NAME
  159.  *    DisplayMessages
  160.  * CALL
  161.  *    DisplayMessages(hd)
  162.  * PARAMETER
  163.  *    hd        handle to open device
  164.  * RETURNS
  165.  *    OS error code
  166.  * GLOBAL
  167.  *    none
  168.  * DESPRIPTION
  169.  *    Displays messages saved during driver startup.
  170.  * REMARKS
  171.  */
  172. int
  173. DisplayMessages(HFILE hd)
  174. {
  175.     APIRET    rc;
  176.     USHORT    cb = 0;                /* keep compiler happy */
  177.     unsigned    i;
  178.     ULONG    datasize;
  179.     DSKSL_MSGS_DATA * data = NULL;
  180.  
  181.     do
  182.     {
  183.     /* First: read size of stored messages */
  184.  
  185.     datasize = sizeof(cb);
  186.     rc = DosDevIOCtl(hd, IOCTL_DSKSLEEP_CATEGORY, DSKSL_READ_MSGS,
  187.              NULL, 0, NULL, &cb, datasize, &datasize);
  188.     if( rc )
  189.     {
  190.         fprintf(stderr, "DSKSL_READ_MSGS - error %lu\n", rc);
  191.         break;
  192.     }
  193.  
  194.     /* Second: allocate buffer big enough to hold
  195.        those messages (but no single byte more) */
  196.  
  197.     datasize = FIELDOFFSET(DSKSL_MSGS_DATA,msg) + (ULONG)cb;
  198.     data = malloc(datasize);
  199.     if( data == NULL )
  200.     {
  201.         fprintf(stderr, "out of memory\n");
  202.         rc = (APIRET)-3;
  203.         break;
  204.     }
  205.  
  206.     /* Third: read and display messages */
  207.  
  208.     rc = DosDevIOCtl(hd, IOCTL_DSKSLEEP_CATEGORY, DSKSL_READ_MSGS,
  209.              NULL, 0, NULL, data, datasize, &datasize);
  210.     if( rc )
  211.     {
  212.         fprintf(stderr, "DSKSL_READ_MSGS - error %lu\n", rc);
  213.         break;
  214.     }
  215.  
  216.     printf("------------------------------"
  217.            "------------------------------\n");
  218.     for( i = 0;
  219.         i < data->cb - FIELDOFFSET(DSKSL_MSGS_DATA,msg);
  220.         i += strlen(&data->msg[i])+1 )
  221.     {
  222.         printf("%s\n", &data->msg[i]);
  223.     }
  224.     printf("------------------------------"
  225.            "------------------------------\n");
  226.     }
  227.     while( 0 );
  228.  
  229.     if( data != NULL )
  230.     free(data);
  231.     return (int)rc;
  232. }
  233.  
  234.  
  235.  
  236.  
  237. /*#
  238.  * NAME
  239.  *    DisplaySettings
  240.  * CALL
  241.  *    DisplaySettings(hd)
  242.  * PARAMETER
  243.  *    hd        handle to open device
  244.  * RETURNS
  245.  *    OS error code
  246.  * GLOBAL
  247.  *    none
  248.  * DESPRIPTION
  249.  *    Displays all devices and timeout values.
  250.  * REMARKS
  251.  */
  252. int
  253. DisplaySettings(HFILE hd)
  254. {
  255.     APIRET        rc;
  256.     ULONG        datasize = 4 + 40 * sizeof(DEVICE_TIMEOUT);
  257.     PDSKSL_QL_DATA  data = malloc( datasize );
  258.     unsigned        i;
  259.  
  260.     if( data == NULL )
  261.     {
  262.     fprintf(stderr, "out of memory\n");
  263.     return -3;
  264.     }
  265.  
  266.     if( fVerbose )
  267.     printf("datasize(in) %lu\n", datasize);
  268.     rc = DosDevIOCtl(hd, IOCTL_DSKSLEEP_CATEGORY, DSKSL_QUERY_TIMEOUT,
  269.              NULL, 0, NULL, data, datasize, &datasize);
  270.     if( fVerbose )
  271.     printf("datasize(out) %lu\n", datasize);
  272.  
  273.     if( rc )
  274.     fprintf(stderr, "DSKSL_QUERY_TIMEOUT - error %lu\n", rc);
  275.     else
  276.     {
  277.     /* Calculate number of entries. */
  278.  
  279.     unsigned cnt = ((data->cb > datasize ?
  280.             datasize : data->cb)
  281.             - FIELDOFFSET(DSKSL_QL_DATA,list))
  282.              / sizeof(data->list[0]);
  283.  
  284.     /* Display nice table */
  285.  
  286.     printf(" Adapter Unit\tMinutes\n");
  287.     for( i = 0; i < cnt; ++i )
  288.         printf(" %3u\t %3u\t %4lu\n",
  289.            data->list[i].adapter, data->list[i].unit,
  290.            data->list[i].seconds / 60UL );
  291.     }
  292.  
  293.     free( data );
  294.     return (int)rc;
  295. }
  296.  
  297.  
  298.          
  299.  
  300. /*#
  301.  * NAME
  302.  *    ChangeSetting
  303.  * CALL
  304.  *    ChangeSetting(hd,a,d,m)
  305.  * PARAMETER
  306.  *    a        adapter index
  307.  *    d        unit index
  308.  *    m        minutes before sleep (0: never)
  309.  * RETURNS
  310.  *    OS error code
  311.  * GLOBAL
  312.  *    none
  313.  * DESPRIPTION
  314.  *    Changes the timeout value for a single device.
  315.  * REMARKS
  316.  */
  317. int
  318. ChangeSetting(HFILE hd,UCHAR a,UCHAR d,ULONG m)
  319. {
  320.     APIRET        rc;
  321.     ULONG        parmsize = sizeof(DSKSL_SETTO_PARM);
  322.     DSKSL_SETTO_PARM    parm;
  323.  
  324.     if( fVerbose )
  325.     printf("--- new: %u %u %lu\n", a, d, m);
  326.  
  327.     parm.cb = (USHORT)parmsize;
  328.     parm.reserved[0] = parm.reserved[1] = 0;
  329.     parm.list[0].adapter = a;
  330.     parm.list[0].unit = d;
  331.     parm.list[0].seconds = m * 60UL;
  332.     parm.list[0].reserved[0] = parm.list[0].reserved[1] = 0;
  333.  
  334.     if( fVerbose )
  335.     printf("parmsize(in) %lu\n", parmsize);
  336.     rc = DosDevIOCtl(hd, IOCTL_DSKSLEEP_CATEGORY, DSKSL_SET_TIMEOUT,
  337.              &parm, parmsize, &parmsize, NULL, 0, NULL);
  338.     if( fVerbose )
  339.     printf("parmsize(out) %lu\n", parmsize);
  340.  
  341.     if( rc )
  342.     fprintf(stderr, "DSKSL_SET_TIMEOUT - error %lu\n", rc);
  343.     return (int)rc;
  344. }
  345.  
  346.  
  347.  
  348.  
  349. /*#
  350.  * NAME
  351.  *    DisplayCurrent
  352.  * CALL
  353.  *    DisplayCurrent(hd)
  354.  * PARAMETER
  355.  *    hd        handle to open device
  356.  * RETURNS
  357.  *    OS error code
  358.  * GLOBAL
  359.  *    none
  360.  * DESPRIPTION
  361.  *    Displays all device timers.
  362.  * REMARKS
  363.  */
  364. int
  365. DisplayCurrent(HFILE hd)
  366. {
  367.     APIRET    rc;
  368.     ULONG    parmsize;
  369.     ULONG    datasize = 4 + 40 * sizeof(DEVICE_TIMEOUT);
  370.     PDSKSL_QL_DATA  data = malloc( datasize );
  371.     unsigned    devcnt;
  372.     unsigned    i;
  373.  
  374.     if( data == NULL )
  375.     {
  376.     fprintf(stderr, "out of memory\n");
  377.     return -3;
  378.     }
  379.  
  380.     do
  381.     {
  382.     if( fVerbose )
  383.         printf("datasize(in) %lu\n", datasize);
  384.     rc = DosDevIOCtl(hd, IOCTL_DSKSLEEP_CATEGORY, DSKSL_QUERY_TIMEOUT,
  385.              NULL, 0, NULL, data, datasize, &datasize);
  386.     if( fVerbose )
  387.         printf("datasize(out) %lu\n", datasize);
  388.  
  389.     if( rc )
  390.     {
  391.         fprintf(stderr, "DSKSL_QUERY_TIMEOUT - error %lu\n", rc);
  392.         break;
  393.     }
  394.  
  395.     /* Calculate number of entries. */
  396.  
  397.     devcnt = ((data->cb > datasize ?
  398.            datasize : data->cb)
  399.           - FIELDOFFSET(DSKSL_QL_DATA,list))
  400.         / sizeof(data->list[0]);
  401.  
  402.     /* Display nice table */
  403.  
  404.     printf(" Adapter Unit\tSeconds\n");
  405.     for( i = 0; i < devcnt; ++i )
  406.     {
  407.         DSKSL_DEVSTATE_PARM    coord;
  408.         DSKSL_DEVSTATE_DATA    current;
  409.  
  410.         coord.adapter = data->list[i].adapter;
  411.         coord.unit = data->list[i].unit;
  412.  
  413.         parmsize = sizeof(coord);
  414.         datasize = sizeof(current);
  415.         if( fVerbose )
  416.         printf("datasize(in) %lu\n", datasize);
  417.         rc = DosDevIOCtl(hd, IOCTL_DSKSLEEP_CATEGORY, DSKSL_QUERY_DEVSTATE,
  418.                  &coord, parmsize, &parmsize,
  419.                  ¤t, datasize, &datasize);
  420.         if( fVerbose )
  421.         printf("datasize(out) %lu\n", datasize);
  422.  
  423.         if( rc )
  424.         {
  425.         fprintf(stderr, "DSKSL_QUERY_DEVSTATE - error %lu\n", rc);
  426.         break;
  427.         }
  428.  
  429.         printf(" %3u\t %3u\t %4lu\n",
  430.            coord.adapter, coord.unit, current.seconds);
  431.     }
  432.     }
  433.     while( 0 );
  434.  
  435.     free( data );
  436.     return (int)rc;
  437. }
  438.  
  439.  
  440.  
  441.  
  442. /*#
  443.  * NAME
  444.  *    ChangeCurrent
  445.  * CALL
  446.  *    ChangeCurrent(hd,a,d,s)
  447.  * PARAMETER
  448.  *    a        adapter index
  449.  *    d        unit index
  450.  *    s        seconds before sleep (0: immediate)
  451.  * RETURNS
  452.  *    OS error code
  453.  * GLOBAL
  454.  *    none
  455.  * DESPRIPTION
  456.  *    Changes the current counter for a single device.
  457.  * REMARKS
  458.  */
  459. int
  460. ChangeCurrent(HFILE hd,UCHAR a,UCHAR d,ULONG s)
  461. {
  462.     APIRET        rc;
  463.     ULONG        parmsize = sizeof(DSKSL_DEVSTATE_PARM);
  464.     DSKSL_DEVSTATE_PARM    parm;
  465.     ULONG        datasize = sizeof(DSKSL_DEVSTATE_DATA);
  466.     DSKSL_DEVSTATE_DATA    data;
  467.  
  468.     if( fVerbose )
  469.     printf("--- new: %u %u %lu\n", a, d, s);
  470.  
  471.     parm.adapter = a;
  472.     parm.unit = d;
  473.     data.seconds = s;
  474.  
  475.     if( fVerbose )
  476.     {
  477.     printf("parmsize(in) %lu\n", parmsize);
  478.     printf("datasize(in) %lu\n", datasize);
  479.     }
  480.     rc = DosDevIOCtl(hd, IOCTL_DSKSLEEP_CATEGORY, DSKSL_SET_DEVSTATE,
  481.              &parm, parmsize, &parmsize,
  482.              &data, datasize, &datasize);
  483.     if( fVerbose )
  484.     {
  485.     printf("parmsize(in) %lu\n", parmsize);
  486.     printf("datasize(in) %lu\n", datasize);
  487.     }
  488.  
  489.     if( rc )
  490.     fprintf(stderr, "DSKSL_SET_DEVSTATE - error %lu\n", rc);
  491.     return (int)rc;
  492. }
  493.  
  494.  
  495.  
  496.  
  497. /*#
  498.  * NAME
  499.  *    main
  500.  * CALL
  501.  *    main(argc,argv)
  502.  * PARAMETER
  503.  *    argc,argv    as usual
  504.  * RETURNS
  505.  *    0        OK
  506.  *    /0        some error
  507.  * GLOBAL
  508.  *    szPrgName, fVerbose
  509.  * DESPRIPTION
  510.  *    Main routine, parses parameter and calls requested
  511.  *    subfunctions.
  512.  * REMARKS
  513.  */
  514. int
  515. main(int argc,char *argv[])
  516. {
  517.     HFILE    hd = 0;
  518.     ULONG    action_taken;
  519.     APIRET    rc;
  520.     int        result;
  521.  
  522.     strcpy( szPrgName, argv[0] );
  523.     while( argc > 1  &&  argv[1][0] == '-' )
  524.     {
  525.     switch( argv[1][1] )
  526.     {
  527.       case '?':
  528.         help();
  529.         return 0;
  530.  
  531.       case 'v':
  532.         fVerbose = 1;
  533.         break;
  534.  
  535.       case 'm':
  536.         fMode = MODE_MESSAGE;
  537.         break;
  538.  
  539.       case 'c':
  540.         fMode = MODE_CHANGE;
  541.         break;
  542.  
  543.       case 'q':
  544.         fMode = MODE_QUERY;
  545.         break;
  546.  
  547.       case 'i':
  548.         fMode = MODE_IMMEDIATE;
  549.         break;
  550.  
  551.       default:
  552.         fprintf(stderr, "%s: unknown arg \"%s\"\n", szPrgName, argv[1]);
  553.         return -1;
  554.     }
  555.     --argc;
  556.     ++argv;
  557.     }
  558.  
  559.     /* Open device driver, no special settings.  Use DENYNONE
  560.      * so other processes (daemon?) may open concurrently. */
  561.  
  562.     rc = DosOpen( DEVICENAME, &hd, &action_taken,
  563.          0, 0,
  564.          OPEN_ACTION_FAIL_IF_NEW|OPEN_ACTION_OPEN_IF_EXISTS,
  565.          OPEN_SHARE_DENYNONE|OPEN_ACCESS_READWRITE,
  566.          NULL );
  567.     if( rc )
  568.     {
  569.     fprintf(stderr, "DosOpen(%s) - error %lu\n", DEVICENAME, rc);
  570.     return (int)rc;
  571.     }
  572.  
  573.     DisplayVersion(hd);                /* always display version */
  574.     switch( fMode )
  575.     {
  576.       case MODE_MESSAGE:
  577.     if( argc != 1 )
  578.     {
  579.         fprintf(stderr, "argument count error\n");
  580.         result = -1;
  581.     }
  582.     else
  583.         result = DisplayMessages(hd);
  584.     break;
  585.  
  586.       case MODE_DISPLAY:
  587.     if( argc != 1 )
  588.     {
  589.         fprintf(stderr, "argument count error\n");
  590.         result = -1;
  591.     }
  592.     else
  593.     {
  594.         printf("Current settings:\n");
  595.         result = DisplaySettings(hd);
  596.     }
  597.     break;
  598.  
  599.       case MODE_CHANGE:
  600.     printf("Current settings:\n");
  601.     result = DisplaySettings(hd);
  602.     if( result != 0 )
  603.         break;                /* don't change */
  604.     if( argc <= 1 )                /* at least one triple */
  605.     {
  606.         fprintf(stderr, "missing device timeout\n");
  607.         result = -1;
  608.     }
  609.     else
  610.     {
  611.         for(; argc > 1; --argc,++argv )
  612.         {
  613.         unsigned a = 0xFF, d = 0xFF;    /* dsksleep won't find them... */
  614.         ULONG     m = 0;
  615.  
  616.         /* Parse argument (spaces important!) and
  617.          * call ChangeSetting(). */
  618.  
  619.         sscanf(argv[1], "%u ,%u ,%lu", &a, &d, &m);
  620.         result = ChangeSetting(hd, (UCHAR)a, (UCHAR)d, m);
  621.         }
  622.         printf("After changing:\n");
  623.         DisplaySettings(hd);        /* ignore errors */
  624.     }
  625.     break;
  626.  
  627.       case MODE_QUERY:
  628.     if( argc != 1 )
  629.     {
  630.         fprintf(stderr, "argument count error\n");
  631.         result = -1;
  632.     }
  633.     else
  634.         result = DisplayCurrent(hd);
  635.     break;
  636.  
  637.       case MODE_IMMEDIATE:
  638.     if( argc <= 1 )                /* at least one triple */
  639.     {
  640.         fprintf(stderr, "missing device timeout\n");
  641.         result = -1;
  642.     }
  643.     else
  644.     {
  645.         for(; argc > 1; --argc,++argv )
  646.         {
  647.         unsigned a = 0xFF, d = 0xFF;    /* dsksleep won't find them... */
  648.         ULONG     m = 0xFFFFFF;
  649.  
  650.         /* Parse argument (spaces important!) and
  651.          * call ChangeCurrent(). */
  652.  
  653.         sscanf(argv[1], "%u ,%u ,%lu", &a, &d, &m);
  654.         result = ChangeCurrent(hd, (UCHAR)a, (UCHAR)d, m);
  655.         }
  656.         printf("After changing:\n");
  657.         DisplayCurrent(hd);            /* ignore errors */
  658.     }
  659.     break;
  660.  
  661.       default:
  662.     result = -1;
  663.     break;
  664.     }
  665.  
  666.     DosClose( hd );                /* be a nice guy */
  667.  
  668.     return result;
  669. }
  670.